{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python 面向对象\n",
    "** 人狗大战设计 **\n",
    "    人狗作战，那至少需要2个角色，一个是人， 一个是狗，且人和狗都有不同的技能，比如人拿棍打狗， 狗可以咬人，怎么描述这种不同的角色和他们的功能呢？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 函数式设计"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "person 严帅 is walking...\n",
      "dog 李磊:wang.wang..wang...wang\n"
     ]
    }
   ],
   "source": [
    "def person(name, age, sex, job):\n",
    "    data = {\n",
    "        'name':name,\n",
    "        'age':age,\n",
    "        'sex':sex,\n",
    "        'job':job\n",
    "    }\n",
    "    return data\n",
    "\n",
    "def dog(name, dog_type):\n",
    "    data = {\n",
    "        'name':name,\n",
    "        'type':dog_type\n",
    "    }\n",
    "    return data\n",
    "\n",
    "# 调用函数\n",
    "d1 = dog(\"李磊\",\"京巴\")\n",
    "p1 = person(\"严帅\",36,\"F\",\"运维\")\n",
    "p2 = person(\"egon\",27,\"F\",\"Teacher\")\n",
    "\n",
    "# 角色对象功能\n",
    "def bark(d):\n",
    "    print(\"dog %s:wang.wang..wang...wang\"%d['name'])\n",
    "    \n",
    "def walk(p):\n",
    "    print(\"person %s is walking...\" %p['name'])\n",
    "walk(p1)\n",
    "bark(d1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 但是人是不可以调用狗的功能的，但上述函数设计没有对此相应设计 **"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 面向对象VS面向过程\n",
    "** 面向过程 **\n",
    "1. 面向过程的程序设计的核心是过程（流水线式思维），过程即解决问题的步骤，面向过程的设计就好比精心设计好一条流水线，考虑周全什么时候处理什么东西。\n",
    "2. 优缺点\n",
    "    * 优点：极大地降低了写程序的复杂度，只需要顺着要执行的步骤，堆叠代码即可。\n",
    "    * 缺点: 一套流水线或者流程就是用来解决一个问题，代码牵一发而动全身。\n",
    "3. 应用场景：一旦完成基本很少改变的场景，著名的例子有Linux内核，git，以及Apache HTTP Server等。\n",
    "\n",
    "** 面向对象 **\n",
    "1. 面向对象的程序设计的核心是对象（上帝式思维），要理解对象为何物，必须把自己当成上帝，上帝眼里世间存在的万物皆为对象，不存在的也可以创造出来。\n",
    "2. 优缺点\n",
    "    * 优点：解决了程序的扩展性。对某一个对象单独修改，会立刻反映到整个体系中，如对游戏中一个任务参数的特征和技能修改都很容易。\n",
    "    * 缺点：可控性差，无法像面对过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果，面向对象的程序一旦开始就由对象之间的交互解决问题，即便是上帝也无法预测最终结果。\n",
    "3. 应用场景：需求经常变化的软件一般需求的变化都集中在用户层，互联网应用，企业内部软件，游戏等都是面向对象的程序设计大显身手的好地方。\n",
    "\n",
    "** 面向对象总结 **\n",
    "在python中面向对象的程序设计并不是全部。\n",
    "面向对象可以使程序的维护和扩展变得更简单，并且可以大大提高程序开发效率，另外基于面向对象的程序可以使他人更加容易理解你的代码逻辑。\n",
    "一些名词：\n",
    "* 类：具有相同特征的一类事物（人、狗、老虎）\n",
    "* 对象/实例：具体的某一个事物（隔壁阿花、留下旺财）\n",
    "* 实例化：类----》对象的过程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 初识Python中的类和对象\n",
    "在python中，用变量表示特征，用函数表示技能，因而具有相同特征和技能的一类事物就是** 类 ** ，对象则是这一类事物中具体的一个。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'eva'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# python中一切皆为对象，类型的本质就是类\n",
    "d = dict(name='eva') # 字典初始化\n",
    "d.pop('name')\n",
    "'''\n",
    "class 类名：\n",
    "    '类的文档字符串'\n",
    "    类体\n",
    "'''\n",
    "# 我们创建一个类\n",
    "class Data:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 类有两种作用：属性引用和实例化\n",
    "### 属性引用（类名.属性）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "person\n",
      "<function Person.walk at 0x0000000004D86510>\n"
     ]
    }
   ],
   "source": [
    "class Person:       # 定义一个人类\n",
    "    role = 'person'  # 人的角色属性都是人\n",
    "    def walk(self):  # 人都可以走路， 也就是有一个走路方法，也叫动态属性\n",
    "        print(\"person is walking...\")\n",
    "\n",
    "print(Person.role)    # 查看人的role属性\n",
    "print(Person.walk)    # 应用人的走路方法，注意，这里不是在调用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例化：类名加括号就是实例化，会自动触发____init____函数的运行，可以用它来为每个实例定制自己的特征\n",
    "实例化的过程就是类----》对象的过程 <br>\n",
    "原本我们只有一个Person类，在这个过程中，产生了一个egg对象，有自己具体的名字、攻击力和生命值。<br>\n",
    "语法：对象名 = 类名（参数）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "person\n",
      "<function Person.walk at 0x000000000503E2F0>\n"
     ]
    }
   ],
   "source": [
    "class Person:  # 定义一个人类\n",
    "    role = 'person'   # 人的角色属性都是人\n",
    "    def __init__(self, name):\n",
    "        self.name = name    # 每一个角色都有自己的昵称\n",
    "    \n",
    "    def walk(self):  #人都可以走路，也就是有一个走路方法\n",
    "        print(\"person is walking...\")\n",
    "\n",
    "print(Person.role)  #查看人的role属性\n",
    "print(Person.walk)  #引用人的走路方法，注意，这里不是在调用\n",
    "\n",
    "egg = Person('egon') # 类名()就等于在执行Person.__init__()\n",
    "# 执行完__init__()就会返回一个对象。这个对象类似一个字典，存在属于这个人本身的一些属性和方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 查看属性&调用方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "egon\n",
      "person is walking...\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print(egg.name)       # 查看属性，直接用对象名.属性名\n",
    "print(egg.walk())     # 调用方法，对象名.方法名()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 关于self\n",
    "self：在实例化时自动将对象/实例本身传给__init__的第一个参数，你也可以给他起个别的名字，但是正常人都不会这么做。因为你瞎改别人就不认识\n",
    "### 类属性的补充\n",
    "一：我们定义的类的属性到底存到哪里了？有两种方式查看\n",
    "1. dir(类名)：查出的是一个名字列表\n",
    "2. 类名.__dict__：查出的是一个字典，key为属性名，value为属性值\n",
    "<br>\n",
    "\n",
    "二：特殊的类属性\n",
    "类名.__name__  # 类的名字（字符串）<br>\n",
    "类名.__doc__   # 类的文档字符串    <br>\n",
    "类名.__base__  # 类的第一个父类    <br>\n",
    "类名.__bases__ # 类所有父类构成的元祖<br>\n",
    "类名.__dict__  # 类的字典属性        <br>\n",
    "类名.__module__# 类定义所在的模块    <br>\n",
    "类名.__class__ # 实例对应的类（仅新式类中）<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "dir(Person)\n",
    "Person.__dict__\n",
    "Person.__name__\n",
    "Person.__base__\n",
    "Person.__bases__\n",
    "Person.__dict__\n",
    "Person.__module__\n",
    "Person.__class__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 给对象添加动作\n",
    "回到咱们的人狗大战：现在我们需要对我们的类做出一点点改变人类除了可以走路之外，还应该具备一些攻击技能。<br>\n",
    "** 1. 对象是关于类而实际存在的一个例子，即实例 ** <br>\n",
    "** 2. 对象/实例只有一种作用：属性引用 **\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "egon\n",
      "10\n",
      "1000\n"
     ]
    }
   ],
   "source": [
    "class Person:   # 定义一个人类\n",
    "    role = 'person'   # 人的角色属性都是人\n",
    "    \n",
    "    def __init__(self, name, aggressivity, life_value):\n",
    "        self.name = name   # 每一个角色都有自己的昵称；\n",
    "        self.aggressivity = aggressivity   # 每一个角色都有自己的攻击力\n",
    "        self.life_value = life_value       # 每一个角色都有自己的生命值\n",
    "        \n",
    "    def attack(self,dog):\n",
    "        # 人可以攻击狗，这里的狗也是一个对象\n",
    "        # 人攻击狗，那么狗的生命值就会根据人的攻击力而下降\n",
    "        dog.life_value -= self.aggressivity\n",
    "\n",
    "egg = Person('egon',10,1000)\n",
    "print(egg.name)\n",
    "print(egg.aggressivity)\n",
    "print(egg.life_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 对象之间的交互\n",
    "现在我们已经有一个人类了，通过给人类一些具体的属性我们就可以拿到一个实实在在的人。现在我们要再创建一个狗类，狗就不能打人了，只能咬人，所以我们给狗一个bite方法。<br>\n",
    "有了狗类，我们还要实例化一只实实在在的狗出来。<br>\n",
    "然后人和狗就可以打架了。现在我们就来让他们打一架吧！\n",
    "## 创建一个狗类\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Dog:   # 定义一个狗类\n",
    "    role = 'dog'   # 狗的角色属性都是狗\n",
    "    \n",
    "    def __init__(self, name, breed, aggressivity, life_value):\n",
    "        self.name = name    # 每一只狗都有自己的昵称\n",
    "        self.breed = breed  # 每一只狗都有自己的品种\n",
    "        self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力\n",
    "        self.life_value = life_value      # 每一只狗都有自己的生命值\n",
    "    \n",
    "    def bite(self, people):\n",
    "        # 狗可以咬人，这里的狗也是一个对象\n",
    "        # 狗咬人， 那么人的生命值就会根据狗的攻击力而下降\n",
    "        dog.life_value -= self.aggressivity\n",
    "\n",
    "# 实例化一只\n",
    "ha2 = Dog('二愣子','哈士奇',10,1000)     "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 交互：egon打ha2一下 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1000\n",
      "990\n"
     ]
    }
   ],
   "source": [
    "print(ha2.life_value)\n",
    "egg.attack(ha2)\n",
    "print(ha2.life_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 两个完整的例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1000\n",
      "990\n"
     ]
    }
   ],
   "source": [
    "class Person:  # 定义一个人类\n",
    "    role = 'person'  # 人的角色属性都是人\n",
    "\n",
    "    def __init__(self, name, aggressivity, life_value):\n",
    "        self.name = name  # 每一个角色都有自己的昵称;\n",
    "        self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;\n",
    "        self.life_value = life_value  # 每一个角色都有自己的生命值;\n",
    "\n",
    "    def attack(self,dog):\n",
    "        # 人可以攻击狗，这里的狗也是一个对象。\n",
    "        # 人攻击狗，那么狗的生命值就会根据人的攻击力而下降\n",
    "        dog.life_value -= self.aggressivity\n",
    "\n",
    "class Dog:  # 定义一个狗类\n",
    "    role = 'dog'  # 狗的角色属性都是狗\n",
    "\n",
    "    def __init__(self, name, breed, aggressivity, life_value):\n",
    "        self.name = name  # 每一只狗都有自己的昵称;\n",
    "        self.breed = breed  # 每一只狗都有自己的品种;\n",
    "        self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;\n",
    "        self.life_value = life_value  # 每一只狗都有自己的生命值;\n",
    "\n",
    "    def bite(self,people):\n",
    "        # 狗可以咬人，这里的狗也是一个对象。\n",
    "        # 狗咬人，那么人的生命值就会根据狗的攻击力而下降\n",
    "        people.life_value -= self.aggressivity\n",
    "\n",
    "egg = Person('egon',10,1000)  #创造了一个实实在在的人egg\n",
    "ha2 = Dog('二愣子','哈士奇',10,1000)  #创造了一只实实在在的狗ha2\n",
    "print(ha2.life_value)         #看看ha2的生命值\n",
    "egg.attack(ha2)               #egg打了ha2一下\n",
    "print(ha2.life_value)         #ha2掉了10点血"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "314.1592653589793 62.83185307179586\n"
     ]
    }
   ],
   "source": [
    "from math import pi\n",
    "\n",
    "class Circle:\n",
    "    '''\n",
    "    定义了一个圆形类；\n",
    "    提供计算面积(area)和周长(perimeter)的方法\n",
    "    '''\n",
    "    def __init__(self,radius):\n",
    "        self.radius = radius\n",
    "\n",
    "    def area(self):\n",
    "         return pi * self.radius * self.radius\n",
    "\n",
    "    def perimeter(self):\n",
    "        return 2 * pi *self.radius\n",
    "\n",
    "\n",
    "circle =  Circle(10) #实例化一个圆\n",
    "area1 = circle.area() #计算圆面积\n",
    "per1 = circle.perimeter() #计算圆周长\n",
    "print(area1,per1) #打印圆面积和周长"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 类命名空间与对象、实例的命名空间\n",
    "** 创建一个类就会创建一个类的名称空间，用来存储类中定义的所有名字，这些名字称为类的属性 ** <br>\n",
    "而类有两种属性：** 静态属性和动态属性 ** <br>\n",
    "* 静态属性就是直接在类中定义的变量\n",
    "* 动态属性就是定义在类中的方法 <br>\n",
    "**  其中类的数据属性是共享给所有对象的 ** <br>\n",
    "** 而类的动态属性是绑定到所有对象的 ** <br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "81983112\n",
      "81983112\n",
      "<bound method Person.attack of <__main__.Person object at 0x0000000004E62860>>\n",
      "<function Person.attack at 0x0000000004E36840>\n"
     ]
    }
   ],
   "source": [
    "print(id(egg.role))\n",
    "print(id(Person.role))\n",
    "print(egg.attack)\n",
    "print(Person.attack)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=\"red\" size=3 face=\"黑体\">创建一个对象/实例就会创建一个对象/实例额名称空间，存放对象/实例的名字，称为对象/实例的属性</font> <br>\n",
    "在obj.name会先从obj自己的名称空间里找name，找不到则去类中找，类也找不到就找父类...最后都找不到就抛出异常"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 面向对象的组合用法\n",
    "<font color=\"red\" size=3 face=\"黑体\">除了继承之外还有另外一种方式，即：组合</font> <br>\n",
    "** 组合指的是，在一个类中以另外一个类的对象作为数据属性，称为累的组合 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-10\n"
     ]
    }
   ],
   "source": [
    "class Weapon:\n",
    "    def prick(self, obj):   # 该装备的主动技能，扎死对方\n",
    "        obj.life_value -= 500   # 假设攻击力为500\n",
    "class Person:\n",
    "    role = 'person'\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        self.weapon = Weapon()   # 给角色绑定一个武器;\n",
    "egg = Person('egon')\n",
    "egg.weapon.prick(ha2)\n",
    "print(ha2.life_value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "314.1592653589793 62.83185307179586\n",
      "94.24777960769379\n",
      "235.61944901923448\n"
     ]
    }
   ],
   "source": [
    "from math import pi\n",
    "\n",
    "class Circle:\n",
    "    '''\n",
    "    定义了一个圆形类；\n",
    "    提供计算面积(area)和周长(perimeter)的方法\n",
    "    '''\n",
    "    def __init__(self, radius):\n",
    "        self.radius = radius\n",
    "    def area(self):\n",
    "        return pi * self.radius * self.radius\n",
    "    def perimeter(self):\n",
    "        return 2 * pi * self.radius\n",
    "\n",
    "circle = Circle(10) \n",
    "area1 = circle.area()\n",
    "per1 = circle.perimeter()\n",
    "print(area1, per1)\n",
    "\n",
    "class Ring:\n",
    "    '''\n",
    "    定义了一个圆环类,提供圆环的面积和周长的方法\n",
    "    '''\n",
    "    def __init__(self, radius_outside, radius_inside):\n",
    "        self.outsid_circle = Circle(radius_outside)\n",
    "        self.inside_circle = Circle(radius_inside)\n",
    "        \n",
    "    def area(self):\n",
    "        return self.outsid_circle.area() - self.inside_circle.area()\n",
    "    \n",
    "    def perimeter(self):\n",
    "        return self.outsid_circle.perimeter() + self.inside_circle.perimeter()\n",
    "\n",
    "ring = Ring(10, 5)\n",
    "print(ring.perimeter())\n",
    "print(ring.area())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color='red' size=4>用组合的方式建立了类与组合的类之间的关系，它是一种‘有’的关系，比如教授有生日，教授教python课程</font> <br>\n",
    "* ** 当类之间有显著不同，并且较小的类是较大的类所需要的组件时，用组合比较好 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1995 1 27\n",
      "python 28000 4 months\n"
     ]
    }
   ],
   "source": [
    "class BirthDate:\n",
    "    def __init__(self,year,month,day):\n",
    "        self.year=year\n",
    "        self.month=month\n",
    "        self.day=day\n",
    "class Course:\n",
    "    def __init__(self,name,price,period):\n",
    "        self.name=name\n",
    "        self.price=price\n",
    "        self.period=period\n",
    "class Teacher:\n",
    "    def __init__(self,name,gender,birth,course):\n",
    "        self.name=name\n",
    "        self.gender=gender\n",
    "        self.birth=birth\n",
    "        self.course=course\n",
    "    \n",
    "    def teach(self):\n",
    "        print('teaching')\n",
    "\n",
    "p1 = Teacher('egon','male',\n",
    "             BirthDate('1995','1','27'),\n",
    "             Course('python','28000','4 months'))\n",
    "print(p1.birth.year,p1.birth.month,p1.birth.day)\n",
    "print(p1.course.name,p1.course.price,p1.course.period)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "400 1100 16\n",
      "1000\n",
      "984\n",
      "484\n"
     ]
    }
   ],
   "source": [
    "# 测试交互,初始面向对象小结\n",
    "class Person:\n",
    "    role = 'person'\n",
    "    def __init__(self,name,aggressivity,life_value,money):\n",
    "        self.name= name\n",
    "        self.aggressivity = aggressivity\n",
    "        self.life_value = life_value\n",
    "        self.money = money\n",
    "    def attack(self,dog):\n",
    "        dog.life_value -= self.aggressivity\n",
    "        \n",
    "class Dog:\n",
    "    role = 'dog'\n",
    "    def __init__(self, name, breed, aggressivity, life_value):\n",
    "        self.name = name  # 每一只狗都有自己的昵称;\n",
    "        self.breed = breed  # 每一只狗都有自己的品种;\n",
    "        self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;\n",
    "        self.life_value = life_value  # 每一只狗都有自己的生命值;\n",
    "    def bite(self,people):\n",
    "        people.life_value -= self.aggressivity\n",
    "\n",
    "class Weapon:\n",
    "    def __init__(self, name, price, aggrev, life_value):\n",
    "        self.name = name\n",
    "        self.price = price\n",
    "        self.aggrev = aggrev\n",
    "        self.life_value = life_value\n",
    "    def update(self, obj):  #obj就是要带这个装备的人\n",
    "        obj.money -= self.price  # 用这个武器的人花钱买所以对应的钱要减少\n",
    "        obj.aggressivity += self.aggrev  # 带上这个装备可以让人增加攻击\n",
    "        obj.life_value += self.life_value  # 带上这个装备可以让人增加生命值\n",
    "    def prick(self, obj):  # 这是该装备的主动技能,扎死对方\n",
    "        obj.life_value -= 500  # 假设攻击力是500\n",
    "        \n",
    "lance = Weapon('长矛',200,6,100)\n",
    "egg = Person('egon',10,1000,600)\n",
    "ha2 = Dog('二愣子','哈士奇',10,1000)\n",
    "\n",
    "if egg.money > lance.price:\n",
    "    lance.update(egg)\n",
    "    egg.weapon = lance\n",
    "\n",
    "print(egg.money, egg.life_value,egg.aggressivity)\n",
    "\n",
    "print(ha2.life_value)\n",
    "egg.attack(ha2)\n",
    "print(ha2.life_value)\n",
    "egg.weapon.prick(ha2)\n",
    "print(ha2.life_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 测试交互,初始面向对象小结"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "400 1100 16\n",
      "<__main__.Weapon object at 0x0000000004E43F60>\n",
      "llll\n",
      "1000\n",
      "984\n",
      "484\n"
     ]
    }
   ],
   "source": [
    "class Person:\n",
    "    role = 'person'\n",
    "    def __init__(self,name,aggressivity,life_value,money):\n",
    "        self.name= name\n",
    "        self.aggressivity = aggressivity\n",
    "        self.life_value = life_value\n",
    "        self.money = money\n",
    "    def attack(self,dog):\n",
    "        dog.life_value -= self.aggressivity\n",
    "        \n",
    "class Dog:\n",
    "    role = 'dog'\n",
    "    def __init__(self, name, breed, aggressivity, life_value):\n",
    "        self.name = name  # 每一只狗都有自己的昵称;\n",
    "        self.breed = breed  # 每一只狗都有自己的品种;\n",
    "        self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;\n",
    "        self.life_value = life_value  # 每一只狗都有自己的生命值;\n",
    "    def bite(self,people):\n",
    "        people.life_value -= self.aggressivity\n",
    "\n",
    "class Weapon:\n",
    "    def __init__(self, name, price, aggrev, life_value):\n",
    "        self.name = name\n",
    "        self.price = price\n",
    "        self.aggrev = aggrev\n",
    "        self.life_value = life_value\n",
    "    def update(self, obj):  #obj就是要带这个装备的人\n",
    "        obj.money -= self.price  # 用这个武器的人花钱买所以对应的钱要减少\n",
    "        obj.aggressivity += self.aggrev  # 带上这个装备可以让人增加攻击\n",
    "        obj.life_value += self.life_value  # 带上这个装备可以让人增加生命值\n",
    "    def prick(self, obj):  # 这是该装备的主动技能,扎死对方\n",
    "        obj.life_value -= 500  # 假设攻击力是500\n",
    "        \n",
    "lance = Weapon('长矛',200,6,100)\n",
    "egg = Person('egon',10,1000,600)\n",
    "ha2 = Dog('二愣子','哈士奇',10,1000)\n",
    "\n",
    "if egg.money > lance.price:\n",
    "    lance.update(egg)\n",
    "    egg.weapon = lance\n",
    "\n",
    "print(egg.money, egg.life_value,egg.aggressivity)\n",
    "print(egg.weapon)\n",
    "egg.ssss = 'llll'\n",
    "print(egg.ssss)\n",
    "print(ha2.life_value)\n",
    "egg.attack(ha2)\n",
    "print(ha2.life_value)\n",
    "egg.weapon.prick(ha2)\n",
    "print(ha2.life_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "print(egg.weapon) <br>\n",
    "egg.ssss = 'llll'  <br>\n",
    "<font color='red'>** 这种语法是对的，可以直接对实例对象添加属性，类似于新建一个名字为egg.ssss的变量 ** </font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
